import './index.css'

import { Button, ConfigProvider } from 'antd'
import React, { useEffect, useState } from 'react'

import $axios from '@/sever'
import { Table } from 'antd'
import type { TableColumnsType } from 'antd'
import { TinyColor } from '@ctrl/tinycolor'
import async from 'async'
import { useComstList } from '@/api/query'

interface DataType {
  // key: React.Key
  name: string
  age: number
  address: string
  sex: number
  birth: string
}

const columns: TableColumnsType<DataType> = [
  {
    title: '姓名',
    dataIndex: 'name'
  },
  {
    title: '年龄',
    dataIndex: 'age',
    sorter: (a, b) => a.age - b.age
  },
  {
    title: '性别',
    dataIndex: 'sex',
    render: (text) => <>{text === 0 ? '男' : '女'}</>
  },
  {
    title: '地址',
    dataIndex: 'address'
  }
]

const ExcelList: React.FC = () => {
  const [pageNum, setpageNum] = useState(1)
  const [pageSize, setpageSize] = useState(5)
  const { data } = useComstList(pageNum, pageSize)
  const [list, setList] = useState([])
  const [total, settotal] = useState(0)
  const batchSize = 500

  const colors1 = ['#6253E1', '#04BEFE']
  const getHoverColors = (colors: string[]) =>
    colors.map((color) => new TinyColor(color).lighten(5).toString())
  const getActiveColors = (colors: string[]) =>
    colors.map((color) => new TinyColor(color).darken(5).toString())

  useEffect(() => {
    if (data?.list) {
      setList(data.list)
      settotal(data.total)
    }
  }, [data])

  const [exporting, setExporting] = useState(false) // 追踪导出状态

  // 定义一个导出特定批次数据的函数
  const exportCsv = async (index) => {
    try {
      // 向后端发送请求以导出指定批次的数据
      await $axios.get(
        `/user/exportBatch?batch=${index}&batchSize=${batchSize}`
      )
    } catch (error) {
      // 捕获并记录错误
      console.error(`Failed to export batch ${index + 1}:`, error)
    }
  }

  // 处理导出按钮点击事件
  const handleExport = async () => {
    if (exporting) {
      return // 如果正在导出，则不执行任何操作
    }
    setExporting(true) // 设置导出状态为真
    console.time('exportData') // 开始计时

    const batchCount = total / batchSize // 假设分成 total / batchSize批，每批100条数据

    try {
      // 使用async.parallelLimit方法并发执行任务数组，限制最大并发数为5
      await async.parallelLimit(
        // 生成一个包含异步任务的数组，每个任务是一个导出特定批次数据的异步函数
        Array.from({ length: batchCount }, (_, index) => async () => {
          await exportCsv(index + 1) // 调用导出特定批次数据的函数
        }),
        5 // 并发数，这里设置为5
      )

      // 所有批次导出完成后，请求服务器合并所有批次并下载最终文件
      const response = await $axios.get(
        `/user/mergeExports?batchCount=${batchCount}`,
        {
          responseType: 'blob'
        }
      )
      const url = window.URL.createObjectURL(new Blob([response])) // 创建下载链接
      const link = document.createElement('a')
      link.href = url
      link.setAttribute('download', 'large-data.xlsx') // 设置下载文件名
      document.body.appendChild(link)
      link.click() // 触发下载
      document.body.removeChild(link) // 删除临时链接
      window.URL.revokeObjectURL(url) // 释放 URL 对象
    } catch (error) {
      // 捕获并记录错误
      console.error('Export failed:', error)
    } finally {
      setExporting(false) // 导出完成后恢复导出状态为假
      console.timeEnd('exportData') // 结束计时
    }
  }

  return (
    <div className="excel-list">
      <ConfigProvider
        theme={{
          components: {
            Button: {
              colorPrimary: `linear-gradient(135deg, ${colors1.join(', ')})`,
              colorPrimaryHover: `linear-gradient(135deg, ${getHoverColors(colors1).join(', ')})`,
              colorPrimaryActive: `linear-gradient(135deg, ${getActiveColors(colors1).join(', ')})`,
              lineWidth: 0
            }
          }
        }}
      >
        <Button type="primary" size="large" onClick={handleExport}>
          {exporting ? 'Exporting...' : 'Export Data'}
        </Button>
      </ConfigProvider>
      <Table
        scroll={{ y: 400 }}
        columns={columns}
        rowKey={function (record) {
          return record._id
        }}
        dataSource={list}
        pagination={{
          current: pageNum,
          pageSize: pageSize,
          total: total,
          showSizeChanger: true,
          showQuickJumper: true,
          onChange: (page, pageSize) => {
            setpageNum(page)
            setpageSize(pageSize)
          }
        }}
      />
    </div>
  )
}

export default ExcelList
